package com.rz.htk.order.task;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.rz.htk.order.entity.Commodity;
import com.rz.htk.order.entity.Order;
import com.rz.htk.order.entity.Pdf;
import com.rz.htk.order.mapper.OrderMapper;
import com.rz.htk.order.service.CommodityService;
import com.rz.htk.order.service.PdfService;
import com.rz.htk.order.task.util.EVSCertifyResponse;
import com.rz.htk.order.task.util.EVSResponse;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import java.io.IOException;
import java.io.StringReader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class USAPDFTask {
    @Resource
    private PdfService pdfService;

    @Resource
    private OrderMapper orderMapper;

    @Resource
    private CommodityService commodityService;

    @Value("${usps.evs.api}")
    private String api;

    @Value("${usps.evs.tagName}")
    private String tagName;

    @Value("${spring.profiles.active}")
    private String active;

    /**
     * 推送订单到美国
     *
     */
    public  void processUSA(Order orders){
        List<Pdf> pdfList = pdfService.getPdfBycode(orders.getCommodityCode());
        if(CollectionUtils.isEmpty(pdfList) || StringUtils.isEmpty(pdfList.get(0).getPdf())) {
            String url = "https://secure.shippingapis.com/ShippingAPI.dll";
            OkHttpClient client = new OkHttpClient();
            FormBody.Builder builder = new FormBody.Builder();
            Map<String, String> map = createXml(orders);
            map.entrySet().iterator().forEachRemaining(item -> builder.add(item.getKey(), item.getValue()));
            FormBody formBody = builder.build();
            Request request = new Request.Builder()
                    .post(formBody)
                    .url(url)
                    .build();
            client.newCall(request).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    System.out.println("===========" + e.getMessage());
                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    String result = response.body().string();
                    try {
                        JAXBContext context = null;
                        Unmarshaller unmarshaller = null;
                        if ("prd".equals(active)) {
                            context = JAXBContext.newInstance(EVSResponse.class);
                            unmarshaller = context.createUnmarshaller();
                        } else {
                            context = JAXBContext.newInstance(EVSCertifyResponse.class);
                            unmarshaller = context.createUnmarshaller();
                        }
                        Pdf pdf = getPdfByOrderId(orders.getId());
                        if (pdf == null) {
                            pdf = new Pdf();
                        }
                        pdf.setCommodityCode(orders.getCommodityCode());
                        pdf.setOrderId(orders.getId());
                        if (result.indexOf("<Error>") > 0) {
                            // EVS返回了错误信息
                            pdf.setRmk(result);
                            orderMapper.updateOrderRmkStateByAfterCode(orders.getAfterCode(),1);
                        } else {
                            if ("prd".equals(active)) {
                                EVSResponse evsResponse = (EVSResponse) unmarshaller.unmarshal(new StringReader(result));
                                pdf.setPdf(evsResponse.getLabelImage());
                                pdf.setAfterCode(evsResponse.getBarcodeNumber());
                                pdf.setRmk(" ");
                            } else {
                                EVSCertifyResponse evsResponse = (EVSCertifyResponse) unmarshaller.unmarshal(new StringReader(result));
                                pdf.setPdf(evsResponse.getLabelImage());
                                pdf.setAfterCode(evsResponse.getBarcodeNumber());
                                pdf.setRmk(" ");
                            }

                        }
                        pdfService.saveOrUpdate(pdf);

                    } catch (Exception e) {
                        orderMapper.updateOrderRmkStateByAfterCode(orders.getAfterCode(),1);
                        log.error("EVS回复内容：" + result);
                        log.error(e.getMessage(), e);
                    }
                }
            });
        }
    }

    public Pdf getPdfByOrderId(Integer orderId){
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("order_id", orderId);
        List<Pdf> list = pdfService.list(queryWrapper);
        if (CollectionUtils.isNotEmpty(list)) {
            return list.get(0);
        }
        return null;
    }

    private  Map<String, String> createXml(Order order){
        List<Commodity> commodities = commodityService.getListCommodityBycode(order.getCommodityCode());
        String xmlcommd ="";
        for(int i =0;i<commodities.size();i++) {
            Commodity com = commodities.get(i);
            xmlcommd += "   <ItemDetail>\n" +
                    "      <Description>"+com.getCommodityName()+"</Description>\n" +
                    "      <Quantity>"+com.getAmount()+"</Quantity>\n" +
                    "      <Value>"+com.getCommodityValue()+"</Value>\n" +
                    "      <NetPounds></NetPounds>\n" +
                    "      <NetOunces>"+ String.format("%.2f", (com.getWeight() * 0.035)) +"</NetOunces>  \n" +
                    "      <HSTariffNumber>" + com.getCustomsCode() + "</HSTariffNumber>\n" +
                    "      <CountryOfOrigin>"+com.getCountryOfOrigin()+"</CountryOfOrigin>\n" +
                    "    </ItemDetail>\n";
        }
        Map<String, String> map = new HashMap<>();
        String serviceType = "priority";
        String container = "RECTANGULAR";
        if ("HTK_P0023".equals(order.getPrdCode())) {
            serviceType = "first class";
            container = "PACKAGE SERVICE";
        }
        String xmldataP="<"+tagName+" USERID=\"624HJEXP0073\">\n" +
                "  <Option>1</Option>\n" +
                "  <Revision>1</Revision>\n" +
                "  <ImageParameters> \n" +
                "    <ImageParameter>4X6LABELP</ImageParameter>\n" +
                "    <LabelSequence> \n" +
                "      <PackageNumber>1</PackageNumber>\n" +
                "      <TotalPackages>1</TotalPackages>\n" +
                "    </LabelSequence> \n" +
                "  </ImageParameters>  \n" +
                "  <FromName>"+order.getSenderName()+"</FromName>\n" +
                "  <FromFirm>"+order.getSenderCompany()+"</FromFirm>\n" +
                "  <FromAddress1>"+order.getSenderAddress()+"</FromAddress1>  \n" +
                "  <FromAddress2>.</FromAddress2>\n" +
                "  <FromCity>"+order.getSenderCity()+"</FromCity>\n" +
                "  <FromState>"+order.getSenderProvince()+"</FromState>  \n" +
                "  <FromZip5>"+order.getSenderPostcode()+"</FromZip5>\n" +
                "  <FromZip4/>\n" +
                "  <FromPhone>"+order.getSenderPhone()+"</FromPhone>\n" +
                "  <POZipCode/>  \n" +
                "  <AllowNonCleansedOriginAddr>false</AllowNonCleansedOriginAddr>\n" +
                "  <ToName>"+order.getRecipientsName()+"</ToName>\n" +
                "  <ToFirm/>  \n" +
                "  <ToAddress1/>\n" +
                "  <ToAddress2>"+order.getRecipientsAddress()+"</ToAddress2>\n" +
                "  <ToCity>"+order.getCity()+"</ToCity>  \n" +
                "  <ToState>"+order.getProvince()+"</ToState>\n" +
                "  <ToZip5>"+order.getRecipientsPostcode()+"</ToZip5>\n" +
                "  <ToZip4/>\n" +
                "  <ToPhone>"+order.getRecipientsPhone()+"</ToPhone>  \n" +
                "  <POBox/>\n" +
                "  <AllowNonCleansedDestAddr/>\n" +
                "  <WeightInOunces>"+ String.format("%.2f", (order.getRoughWeight() * 0.035)) + "</WeightInOunces>  \n" +
                "  <ServiceType>" + serviceType + "</ServiceType>  \n" +
                "  <Container>"+container+"</Container>  \n" +
                "  <Width>"+order.getWidth()+"</Width>  \n" +
                "  <Length>"+order.getLongs()+"</Length>  \n" +
                "  <Height>"+order.getHigh()+"</Height>  \n" +
                "  <Machinable/>  \n" +
                "  <ProcessingCategory/>  \n" +
                "  <PriceOptions>Commercial Plus</PriceOptions>  \n" +
                "  <InsuredAmount/>\n" +
                "  <AddressServiceRequested/>\n" +
                "  <ExpressMailOptions>\n" +
                "    <DeliveryOption/>\n" +
                "    <WaiverOfSignature/> \n" +
                "  </ExpressMailOptions>\n" +
                "  <ShipDate/>\n" +
                "  <CustomerRefNo></CustomerRefNo>\n" +
                "  <ExtraServices>\n" +
                "    <ExtraService/>\n" +
                "  </ExtraServices>\n" +
                "  <HoldForPickup/>  \n" +
                "  <OpenDistribute/>\n" +
                "  <PermitNumber/>\n" +
                "  <PermitZIPCode/>\n" +
                "  <PermitHolderName/>  \n" +
                "  <SenderName/>\n" +
                "  <SenderEMail/>  \n" +
                "  <RecipientName>"+order.getSenderName()+"</RecipientName>\n" +
                "  <RecipientEMail/>\n" +
                "  <ReceiptOption/>  \n" +
                "  <ImageType>PDF</ImageType>\n" +
                "  <HoldForManifest>Y</HoldForManifest>\n" +
                "  <NineDigitRoutingZip/>\n" +
                "  <ShippingContents> \n" +
                        xmlcommd+
                "  </ShippingContents>\n" +
                "  <CustomsContentType>MERCHANDISE</CustomsContentType>  \n" +
                "  <AltReturnAddress1/>\n" +
                "  <AltReturnAddress2/>\n" +
                "  <AltReturnAddress3/>\n" +
                "</"+tagName+">\n";
        //map.put("API", "eVSCertify");
        map.put("API", api);
        map.put("XML", xmldataP);

        log.info("向USPS-EVS系统发送面单请求：" + xmldataP);
        return map;
    }
}
